home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / COMMS / C028.ZIP / RBSB.C < prev    next >
Text File  |  1990-01-31  |  7KB  |  314 lines

  1. /*
  2.  *
  3.  *  Rev 05-05-1988
  4.  *  This file contains Unix specific code for setting terminal modes,
  5.  *  very little is specific to ZMODEM or YMODEM per se (that code is in
  6.  *  sz.c and rz.c).  The CRC-16 routines used by XMODEM, YMODEM, and ZMODEM
  7.  *  are also in this file, a fast table driven macro version
  8.  *
  9.  *    V7/BSD HACKERS:  SEE NOTES UNDER mode(2) !!!
  10.  *
  11.  *   This file is #included so the main file can set parameters such as HOWMANY.
  12.  *   See the main files (rz.c/sz.c) for compile instructions.
  13.  */
  14.  
  15. #ifdef V7
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <sgtty.h>
  19. #define OS "V7/BSD"
  20. #ifdef LLITOUT
  21. long Locmode;        /* Saved "local mode" for 4.x BSD "new driver" */
  22. long Locbit = LLITOUT;    /* Bit SUPPOSED to disable output translations */
  23. #include <strings.h>
  24. #endif
  25. #endif
  26.  
  27. #ifndef OS
  28. #ifndef USG
  29. #define USG
  30. #endif
  31. #endif
  32.  
  33. #ifdef USG
  34. #include <sys/types.h>
  35. #include <sys/stat.h>
  36. #include <termio.h>
  37. #include <sys/ioctl.h>
  38. #define OS "SYS III/V"
  39. #define MODE2OK
  40. #include <string.h>
  41. #endif
  42.  
  43. #if HOWMANY  > 255
  44. Howmany must be 255 or less
  45. #endif
  46.  
  47. /*
  48.  * return 1 iff stdout and stderr are different devices
  49.  *  indicating this program operating with a modem on a
  50.  *  different line
  51.  */
  52. int Fromcu;        /* Were called from cu or yam */
  53. from_cu()
  54. {
  55.     struct stat a, b;
  56.  
  57.     fstat(1, &a); fstat(2, &b);
  58.     Fromcu = a.st_rdev != b.st_rdev;
  59.     return;
  60. }
  61. cucheck()
  62. {
  63.     if (Fromcu)
  64.         fprintf(stderr,"Please read the manual page BUGS chapter!\r\n");
  65. }
  66.  
  67.  
  68. struct {
  69.     unsigned baudr;
  70.     int speedcode;
  71. } speeds[] = {
  72.     110,    B110,
  73.     300,    B300,
  74.     600,    B600,
  75.     1200,    B1200,
  76.     2400,    B2400,
  77.     4800,    B4800,
  78.     9600,    B9600,
  79.     19200,    EXTA,
  80.     38400,    EXTB,
  81.     0,
  82. };
  83.  
  84. int Twostop;        /* Use two stop bits */
  85.  
  86.  
  87. #ifndef READCHECK
  88. #ifdef FIONREAD
  89. #define READCHECK
  90. /*
  91.  *  Return non 0 iff something to read from io descriptor f
  92.  */
  93. rdchk(f)
  94. {
  95.     static long lf;
  96.  
  97.     ioctl(f, FIONREAD, &lf);
  98.     return ((int) lf);
  99. }
  100. #endif
  101. #ifdef SV
  102. #define READCHECK
  103. #include <fcntl.h>
  104.  
  105. char checked = '\0' ;
  106. /*
  107.  * Nonblocking I/O is a bit different in System V, Release 2
  108.  */
  109. rdchk(f)
  110. {
  111.     int lf, savestat;
  112.  
  113.     savestat = fcntl(f, F_GETFL) ;
  114.     fcntl(f, F_SETFL, savestat | O_NDELAY) ;
  115.     lf = read(f, &checked, 1) ;
  116.     fcntl(f, F_SETFL, savestat) ;
  117.     return(lf) ;
  118. }
  119. #endif
  120. #endif
  121.  
  122.  
  123. static unsigned
  124. getspeed(code)
  125. {
  126.     register n;
  127.  
  128.     for (n=0; speeds[n].baudr; ++n)
  129.         if (speeds[n].speedcode == code)
  130.             return speeds[n].baudr;
  131.     return 38400;    /* Assume fifo if ioctl failed */
  132. }
  133.  
  134.  
  135.  
  136. #ifdef ICANON
  137. struct termio oldtty, tty;
  138. #else
  139. struct sgttyb oldtty, tty;
  140. struct tchars oldtch, tch;
  141. #endif
  142.  
  143. int iofd = 0;        /* File descriptor for ioctls & reads */
  144.  
  145. /*
  146.  * mode(n)
  147.  *  3: save old tty stat, set raw mode with flow control
  148.  *  2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
  149.  *  1: save old tty stat, set raw mode 
  150.  *  0: restore original tty mode
  151.  */
  152. mode(n)
  153. {
  154.     static did0 = FALSE;
  155.  
  156.     vfile("mode:%d", n);
  157.     switch(n) {
  158. #ifdef USG
  159.     case 2:        /* Un-raw mode used by sz, sb when -g detected */
  160.         if(!did0)
  161.             (void) ioctl(iofd, TCGETA, &oldtty);
  162.         tty = oldtty;
  163.  
  164.         tty.c_iflag = BRKINT|IXON;
  165.  
  166.         tty.c_oflag = 0;    /* Transparent output */
  167.  
  168.         tty.c_cflag &= ~PARENB;    /* Disable parity */
  169.         tty.c_cflag |= CS8;    /* Set character size = 8 */
  170.         if (Twostop)
  171.             tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  172.  
  173.  
  174. #ifdef READCHECK
  175.         tty.c_lflag = Zmodem ? 0 : ISIG;
  176.         tty.c_cc[VINTR] = Zmodem ? -1:030;    /* Interrupt char */
  177. #else
  178.         tty.c_lflag = ISIG;
  179.         tty.c_cc[VINTR] = Zmodem ? 03:030;    /* Interrupt char */
  180. #endif
  181.         tty.c_cc[VQUIT] = -1;            /* Quit char */
  182. #ifdef NFGVMIN
  183.         tty.c_cc[VMIN] = 1;
  184. #else
  185.         tty.c_cc[VMIN] = 3;     /* This many chars satisfies reads */
  186. #endif
  187.         tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  188.  
  189.         (void) ioctl(iofd, TCSETAW, &tty);
  190.         did0 = TRUE;
  191.         return OK;
  192.     case 1:
  193.     case 3:
  194.         if(!did0)
  195.             (void) ioctl(iofd, TCGETA, &oldtty);
  196.         tty = oldtty;
  197.  
  198.         tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK;
  199.  
  200.          /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
  201.         tty.c_lflag &= ~(ECHO | ICANON | ISIG);
  202.  
  203.         tty.c_oflag = 0;    /* Transparent output */
  204.  
  205.         tty.c_cflag &= ~PARENB;    /* Same baud rate, disable parity */
  206.         tty.c_cflag |= CS8;    /* Set character size = 8 */
  207.         if (Twostop)
  208.             tty.c_cflag |= CSTOPB;    /* Set two stop bits */
  209. #ifdef NFGVMIN
  210.         tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
  211. #else
  212.         tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
  213. #endif
  214.         tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  215.         (void) ioctl(iofd, TCSETAW, &tty);
  216.         did0 = TRUE;
  217.         Baudrate = getspeed(tty.c_cflag & CBAUD);
  218.         return OK;
  219. #endif
  220. #ifdef V7
  221.     /*
  222.      *  NOTE: this should transmit all 8 bits and at the same time
  223.      *   respond to XOFF/XON flow control.  If no FIONREAD or other
  224.      *   READCHECK alternative, also must respond to INTRRUPT char
  225.      *   This doesn't work with V7.  It should work with LLITOUT,
  226.      *   but LLITOUT was broken on the machine I tried it on.
  227.      */
  228.     case 2:        /* Un-raw mode used by sz, sb when -g detected */
  229.         if(!did0) {
  230.             ioctl(iofd, TIOCEXCL, 0);
  231.             ioctl(iofd, TIOCGETP, &oldtty);
  232.             ioctl(iofd, TIOCGETC, &oldtch);
  233. #ifdef LLITOUT
  234.             ioctl(iofd, TIOCLGET, &Locmode);
  235. #endif
  236.         }
  237.         tty = oldtty;
  238.         tch = oldtch;
  239. #ifdef READCHECK
  240.         tch.t_intrc = Zmodem ? -1:030;    /* Interrupt char */
  241. #else
  242.         tch.t_intrc = Zmodem ? 03:030;    /* Interrupt char */
  243. #endif
  244.         tty.sg_flags |= (ODDP|EVENP|CBREAK);
  245.         tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);
  246.         ioctl(iofd, TIOCSETP, &tty);
  247.         ioctl(iofd, TIOCSETC, &tch);
  248. #ifdef LLITOUT
  249.         ioctl(iofd, TIOCLBIS, &Locbit);
  250. #endif
  251.         bibi(99);    /* un-raw doesn't work w/o lit out */
  252.         did0 = TRUE;
  253.         return OK;
  254.     case 1:
  255.     case 3:
  256.         if(!did0) {
  257.             ioctl(iofd, TIOCEXCL, 0);
  258.             ioctl(iofd, TIOCGETP, &oldtty);
  259.             ioctl(iofd, TIOCGETC, &oldtch);
  260. #ifdef LLITOUT
  261.             ioctl(iofd, TIOCLGET, &Locmode);
  262. #endif
  263.         }
  264.         tty = oldtty;
  265.         tty.sg_flags |= RAW;
  266.         tty.sg_flags &= ~ECHO;
  267.         ioctl(iofd, TIOCSETP, &tty);
  268.         did0 = TRUE;
  269.         Baudrate = getspeed(tty.sg_ospeed);
  270.         return OK;
  271. #endif
  272.     case 0:
  273.         if(!did0)
  274.             return ERROR;
  275. #ifdef USG
  276.         (void) ioctl(iofd, TCSBRK, 1);    /* Wait for output to drain */
  277.         (void) ioctl(iofd, TCFLSH, 1);    /* Flush input queue */
  278.         (void) ioctl(iofd, TCSETAW, &oldtty);    /* Restore modes */
  279.         (void) ioctl(iofd, TCXONC,1);    /* Restart output */
  280. #endif
  281. #ifdef V7
  282.         ioctl(iofd, TIOCSETP, &oldtty);
  283.         ioctl(iofd, TIOCSETC, &oldtch);
  284.         ioctl(iofd, TIOCNXCL, 0);
  285. #ifdef LLITOUT
  286.         ioctl(iofd, TIOCLSET, &Locmode);
  287. #endif
  288. #endif
  289.  
  290.         return OK;
  291.     default:
  292.         return ERROR;
  293.     }
  294. }
  295.  
  296. sendbrk()
  297. {
  298. #ifdef V7
  299. #ifdef TIOCSBRK
  300. #define CANBREAK
  301.     sleep(1);
  302.     ioctl(iofd, TIOCSBRK, 0);
  303.     sleep(1);
  304.     ioctl(iofd, TIOCCBRK, 0);
  305. #endif
  306. #endif
  307. #ifdef USG
  308. #define CANBREAK
  309.     ioctl(iofd, TCSBRK, 0);
  310. #endif
  311. }
  312.  
  313. /* End of rbsb.c */
  314.